package com.clf.data.redis.core.json.ops.impl;

import com.alibaba.fastjson.TypeReference;
import com.clf.data.redis.core.json.FastJsonRedisTemplate;
import com.clf.data.redis.core.json.ops.FastJsonBoundValueOperations;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.BoundValueOperations;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * ops覆盖类，可提供原先ops没有的方法
 * 
 * @author <a href="mailto:zhudelie@zuozh.com">zhudelie</a>
 * @version
 * @since JDK 1.6 create on 2017年3月31日 Copyright 2017 ZZJR All Rights Reserved.
 *
 */
public class FastJsonBoundValueOperationsImpl<K, V> extends OperationsAware<K, V> implements FastJsonBoundValueOperations<K, V> {
	private BoundValueOperations<K, V> ops;
	public FastJsonBoundValueOperationsImpl(BoundValueOperations<K, V> ops, FastJsonRedisTemplate<K, V> template) {
		super(template);
		this.ops = ops;
	}
	
	public BoundValueOperations getOps(){
		return ops;
	}
	/**
	 * 获得key
	 */
	@Override
	public K getKey() {
		// TODO Auto-generated method stub
		return (K) getOps().getKey();
	}
	/**
	 * 获得类型
	 */
	@Override
	public DataType getType() {
		// TODO Auto-generated method stub
		return getOps().getType();
	}
	/**
	 * 获得过期时间
	 */
	@Override
	public Long getExpire() {
		// TODO Auto-generated method stub
		return getOps().getExpire();
	}
	/**
	 * 设置过期时间
	 */
	@Override
	public Boolean expire(long timeout, TimeUnit unit) {
		// TODO Auto-generated method stub
		return getOps().expire(timeout, unit);
	}
	/**
	 * 设置过期时间
	 */
	@Override
	public Boolean expireAt(Date date) {
		// TODO Auto-generated method stub
		return getOps().expireAt(date);
	}
	/**
	 * 取消过期时间
	 */
	@Override
	public Boolean persist() {
		// TODO Auto-generated method stub
		return getOps().persist();
	}
	/**
	 * 重命名key
	 */
	@Override
	public void rename(K newKey) {
		getOps().rename(newKey);
	}
	/**
	 * 设置值
	 */
	@Override
	public void set(Object value) {
		// TODO Auto-generated method stub
		getOps().set( value);
	}
	/**
	 * 设置值，并设置过期时间
	 */
	@Override
	public void set(Object value, long timeout, TimeUnit unit) {
		// TODO Auto-generated method stub
		getOps().set( value, timeout, unit);
	}
	/**
	 * 设置值，如果当前值为空的话
	 */
	@Override
	public Boolean setIfAbsent(V value) {
		// TODO Auto-generated method stub
		return getOps().setIfAbsent( value);
	}
	/**
	 * 获取值
	 */
	@Override
	public V get() {
		// TODO Auto-generated method stub
		return (V) getOps().get();
	}
	/**
	 * 获取值,同时设置一个新值
	 */
	@Override
	public V getAndSet(V value) {
		// TODO Auto-generated method stub
		return (V) getOps().getAndSet(value);
	}
	/**
	 * 自增
	 */
	@Override
	public Long increment(long delta) {
		// TODO Auto-generated method stub
		return getOps().increment(delta);
	}
	/**
	 * 自增
	 */
	@Override
	public Double increment(double delta) {
		// TODO Auto-generated method stub
		return getOps().increment(delta);
	}
	/**
	 * 追加字符串
	 */
	@Override
	public Integer append(String value) {
		// TODO Auto-generated method stub
		return getOps().append(value);
	}
	/**
	 * 获得字符串中的一部分
	 */
	@Override
	public String get(long start, long end) {
		// TODO Auto-generated method stub
		return getOps().get(start, end);
	}

	@Override
	public void set(V value, long offset) {
		getOps().set(value, offset);
	}

	@Override
	public Long size() {
		// TODO Auto-generated method stub
		return getOps().size();
	}

	//@Override
	/*public void set(V value, DBExecutor<Object> db) {
		set(value, db, null, null);
	}*/

	/**
	 * 获得指定类型的值
	 * @param type
	 * @return
	 */
	@Override
	public <T> T get(Class<T> type) {
		template.setConvertType(type);
		return (T) get();
	}

	/*public V get(DBExecutor<V> db) {
		return get(db, null, null);
	}*/

	/*public <T> T get(Class<T> type, DBExecutor<T> db) {
		return get(type, db, null, null);
	}*/
	/**
	 *  得到一个list类型的值
	 * @return
	 */
	@Override
	public List<V> getList() {
		template.setConvertType(new TypeReference<List<V>>() {
		});
		return (List<V>) get();
	}

	/*public List<V> getList(DBExecutor<List<V>> db) {
		return getList(db, null, null);
	}*/
	/**
	 * 得到一个list类型的值，list里面的元素类型为指定类型
	 * @param type
	 * @return
	 */
	@Override
	public  <T>  List<T> getList(Class<T> type) {
		template.setConvertType(new TypeReference<List<T>>(type) {
		});
		return (List<T>) get();
	}


	/*public  <T>  List<T> getList(Class<T> type, DBExecutor<List<T>> db) {
		return getList(type, db, null, null);
	}*/

	/*public void set(V value, DBExecutor<Object> db, Long timeout, TimeUnit unit) {
		boolean needEx = false;
		if (timeout != null) {
			if (unit == null) {
				unit = TimeUnit.SECONDS;
			}
			needEx = !template.hasKey(this.getKey());
		}
		set(value, timeout, unit);
		if (needEx) {
			template.expire(this.getKey(), timeout, unit);
		}
		db.execute(getKey(), value, timeout, unit);
	}*/

	
	/*public V get(DBExecutor<V> db, Long timeout, TimeUnit unit) {
		V v = get();
		if (v == null) {
			v = db.execute();
			if (v != null) {
				set(v);
				expire(timeout, unit);
			}
		}
		return v;
	}*/

	
	/*public  <T> T  get(Class<T> type, DBExecutor<T> db, Long timeout, TimeUnit unit) {
		T v = get(type);
		if (v == null) {
			v = db.execute(getKey(), type);
			if (v != null) {
				set(v);
				expire0(timeout, unit);
			}
		}
		return v;
	}*/

	
	/*public List<V> getList(DBExecutor<List<V>> db, Long timeout, TimeUnit unit) {
		List<V> list = getList();
		if (list == null || list.isEmpty()) {
			List<V> list2 = db.execute(getKey());
			if (list2 != null) {
				list = list2;
				if (!list2.isEmpty()) {
					set(list2);
					expire0(timeout, unit);
				}
			}
		}
		return list;
	}*/

	
	/*public <T>  List<T> getList(Class<T> type, DBExecutor<List<T>> db, Long timeout, TimeUnit unit) {
		List<T> list = getList(type);
		if (list == null || list.isEmpty()) {
			List<T> list2 = db.execute(getKey(), type);
			if (list2 != null) {
				list = list2;
				if (!list2.isEmpty()) {
					set(list2);
					expire0(timeout, unit);
				}
			}
		}
		return list;
	}*/

	private void expire0(Long timeout, TimeUnit unit) {
		if (timeout != null) {
			if (unit == null) {
				unit = TimeUnit.SECONDS;
			}
			expire(timeout, unit);
		}
	}
}
